/*******************************************************************************
 * Copyright (c) 2007 University of Oslo.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     University of Oslo - initial API and implementation
 *******************************************************************************/

package com.cea.papyrus.diagram.sequence.sedi.edit;

import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.gef.GraphicalEditPart;
import org.eclipse.uml2.uml.NamedElement;

import com.cea.papyrus.core.editor.ModelManager;
import com.cea.papyrus.diagram.sequence.sedi.figures.SeDiSubpartFigure;
import com.cea.papyrus.diagraminterchange2.di2.Di2Package;
import com.cea.papyrus.diagraminterchange2.di2.GraphElement;
import com.cea.papyrus.diagraminterchange2.di2.GraphNode;

/**
 * Abstract edit part for graphical model elements.
 * 
 * @author frankd@ifi.uio.no
 */
public abstract class AbstractGraphicalEditPart<T extends NamedElement> extends
        AbstractNamedEditPart<T> {

    public AbstractGraphicalEditPart(GraphElement model, ModelManager modelManager) {
        super(model, modelManager);
    }

    @Override
    protected void refreshVisuals() {
        super.refreshVisuals();
        IFigure figure = this.getFigure();
        if (figure instanceof SeDiSubpartFigure && this.getModel() instanceof GraphElement) {
            ((SeDiSubpartFigure) figure).refreshAll((GraphElement) this.getModel());
        }
        refreshVisualsBounds();
    }

    /** Subclasses might override to provide different update algorithms. */
    @SuppressWarnings("unchecked")
    protected void refreshVisualsBounds() {
        GraphNode model = (GraphNode) getModel();
        SeDiSubpartFigure figure = (SeDiSubpartFigure) getFigure();

        // Any such adjustment should happen in a command
        Rectangle bounds = new Rectangle(model.getPosition(), model.getSize());
        Rectangle preferred = figure.getPreferredBounds(bounds);
        if (!preferred.equals(bounds)) {
            model.setSize(preferred.getSize());
            model.setPosition(preferred.getLocation());
        }

        if (getParent() != null) // may not be null: when the EP is removed
            ((GraphicalEditPart) getParent()).setLayoutConstraint(this, figure, preferred);
        figure.setBounds(preferred); // experimental

        // GraphicalElement model = (GraphicalElement) getModel();
        // ((GraphicalEditPart)getParent()).
        // setLayoutConstraint(this, getFigure(), model.getBounds());
    }

    @Override
    protected void graphicalModelChanged(Notification evt) {
        switch (evt.getFeatureID(Di2Package.class)) {
        case Di2Package.GRAPH_NODE__SIZE:
        case Di2Package.GRAPH_NODE__POSITION:
            refreshVisuals();
            break;
        default:
            super.graphicalModelChanged(evt);
        }
    }
}
